clc,clear,close all;
% N:5*2
N=[4 4; 8 4; 15 8;24 4; 24 12];
% N = [0 0; .5 0;0 2; 2 2;2.5 8; 6 3; 7 3];
% N=[ 1 1; 1.5 1.5;5 5; 3 4;4 4 ; 3 3.5]
[m,n] = size(N);
for i=1:m
    for j=1:m
        % 计算5个个体之间的欧氏距离
        mini_dist =(N(i,1)-N(j,1))^2 +(N(i,2)-N(j,2))^2;
        mini_dist = sqrt(mini_dist);
        % ty:5*5
        ty(i,j) = mini_dist;
    end
end


while 1

    disp("原始的距离矩阵：");
    disp(ty);

    % 寻找聚类的两个个体
    [l,z]=min_dist(ty);

    % 更新距离矩阵
    [ty,z] = single(ty,l,z);
    %[ty,z] = weighted(ty,l,z);
    %[ty,z] = comlete(ty,l,z);
    disp("聚类更新后的距离矩阵：");
    disp(ty);

    % 删除重复个体
    [ty]= delete(ty,l);
    [d,e]=size(ty);
    disp(ty);

    if d==2 && e==2
        break;
    end
    disp("----------------------------------------------------");
end

% 删除重复的行和列
function [my]= delete(my,l)
my([l],:) = [];
my(:,[l])=[];
fprintf("删除第%d行与%d列\n",l,l);
end


% 聚类后，更新新产生的个体到其他个体的距离,这里采用最短距离更新
%Single Linkage的计算方法是计算两个组合数据点中的每个数据点与其他所有数据点的距离.将所有距离最小的作为这两个组合数据点的距离
function [ty,z] = single(ty,l,z)
o = size(ty,1);
for j=1:o
    if(ty(l,j)> ty(z,j))
        ty(l,j)=ty(z,j);
        ty(j,l)=ty(l,j);
    else
        ty(z,j)=ty(l,j);
        ty(j,z)=ty(z,j);
    end
end
end

% Average Linkage的计算方法是计算两个组合数据点中的每个数据点与其他所有数据点的距离.将所有距离的均值作为两个组合数据点间的距离.
function [ty,z] = weighted(ty,l,z)
[o,p] = size(ty);
for j=1:o
    if  ty(l,j)>0 && ty(z,j)>0
        lj = ty(l,j);
        ty(l,j) = (ty(l,j)+ty(z,j))/2;
        ty(j,l) = ty(l,j);
        ty(z,j) = (lj+ty(z,j))/2;
        ty(j,z) = ty(z,j);
    else
        ty(l,j) = 0;
        ty(j,l) = 0;
        ty(z,j) = 0;
        ty(j,z) = 0;

    end
end
end

% Complete Linkage的计算方法是计算两个组合数据点中的每个数据点与其他所有数据点的距离.将所有距离最大的作为这两个组合数据点的距离
function [ty,z] = comlete(ty,l,z)
o = size(ty,1);
for j=1:o
    if ty(l,j)==0 || ty(z,j)==0
        ty(l,j) = 0;
        ty(j,l) = 0;
        ty(z,j) = 0;
        ty(j,z) = 0;
    elseif ty(l,j) < ty(z,j)
        ty(l,j)=ty(z,j);
        ty(j,l)=ty(l,j);
    elseif ty(l,j) > ty(z,j)
        ty(z,j)=ty(l,j);
        ty(j,z)=ty(z,j);
    end
end
end

% 取5*5=25个距离中最小的那一个,但是不取距离为0的个体下标
function [l,z] = min_dist(ty)
[m,n]=size(ty);
l=0;
z=0;
mino=inf;
for i=1:m
    for j=(i+1):m
        if  ty(i,j)<mino
            mino=ty(i,j);
            l=i;
            z=j;
        end
    end
end
fprintf("第%d行与%d行最近,为同一类\n",l,z);
end
